package com.sci99.script;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.apache.ibatis.io.Resources;

public class TestJS {
	static Logger log = Logger.getAnonymousLogger();

	public static void main(String[] args) {
		ScriptEngineManager sem = new ScriptEngineManager();
		ScriptEngine se = sem.getEngineByName("javascript");

		try {
			// 调用直接JAVASCRIPT语句
			se.eval("println('111');");
			String tmpstr = "test string";
			se.eval(("println('" + tmpstr + "');"));

			// 调用无参数方法JAVASCRIPT函数
			se.eval("function sayHello() {"
					+ " println('Hello '+strname+'!');return 'my name is '+strname;"
					+ "}");
			Invocable invocableEngine = (Invocable) se;
			se.put("strname", "testname");
			String callbackvalue = (String) invocableEngine
					.invokeFunction("sayHello");
			log.info(callbackvalue);

			// 调用有参数JAVASCRIPT函数
			se.eval("function sayHello2(strname2) {"
					+ " println('Hello '+strname+'!');return 'my name is '+strname2;"
					+ "}");
			callbackvalue = (String) invocableEngine.invokeFunction(
					"sayHello2", "testname2");
			log.info(callbackvalue);

			args(se);
		} catch (ScriptException e) {
			log.log(Level.SEVERE, e.getMessage(), e);

		} catch (NoSuchMethodException e) {
			log.log(Level.SEVERE, e.getMessage(), e);
		}
		runfile(se);
	}

	public static void doSwing(ScriptEngine se) throws ScriptException,
			NoSuchMethodException {

		// Packages是脚本语言里的一个全局变量,专用于访问JDK的package
		se.eval("function doSwing(t){"
				+ "var f=new Packages.javax.swing.JFrame(t);f.setSize(400,300);"
				+ "f.setDefaultCloseOperation(Packages.javax.swing.JFrame.EXIT_ON_CLOSE);"
				+ "f.setVisible(true);}");
		// Invocable 接口: 允许java平台调用脚本程序中的函数或方法
		Invocable inv = (Invocable) se;
		// invokeFunction()中的第一个参数就是被调用的脚本程序中的函数，第二个参数是传递给被调用函数的参数；
		inv.invokeFunction("doSwing", "Scripting Swing");
	}

	public static void args(ScriptEngine se) throws ScriptException {
		Map<String, String> m = new HashMap<>();
		m.put("kkk", "test");
		se.put("fm", m);
		se.eval("println(fm.get('kkk'))");
		se.eval("println(Packages.com.sci99.ex.vm.Msg.OptOK)");
		se.eval("fm.put('vvv','123')");
		log.info(m.toString());
	}

	public static void runfile(ScriptEngine se) {
		try {
			InputStream in = Resources.getResourceAsStream("test.js");
			Date d = new Date();
			Reader r = new InputStreamReader(in);
			se.eval(r);
			System.out.println(new Date().getTime() - d.getTime());
		} catch (IOException | ScriptException e) {
			log.log(Level.SEVERE, e.getMessage(), e);
		}
	}
}
